﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net.Sockets; //使用Socket需要；
using System.Net; //使用IPAddress需要；
using System.Data.OleDb; //连接Access数据库用；
using System.Data;//CommandBehavior需要；

namespace OrderFoodAdmin
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Socket socket;
        OleDbConnection objConnection; //数据库连接；
        OleDbCommand sqlcmd; //数据库命令；
        OleDbDataReader reader; //读取的数据；
        const int N_FOODS = 20; //载入多少道菜； 
        public MainWindow()
        {
            InitializeComponent();
        }
        private void showText(TextBlock tb, string text)
        {
            tb.Text = text;
            //在代码中设置事件处理函数，大概是委托机制；
            tb.MouseRightButtonDown += new MouseButtonEventHandler(showTextBlockOut);
        }
        private void showTextBlockOut(object sender, System.EventArgs e)
        {
            MessageBox.Show(mainWindow, ((TextBlock)sender).Text.ToString());
        }
        private bool connectDB()
        {
            bool isGotDB = false; //是否成功连接数据库；
            try
            { //连接数据库；
                //构造连接字符串
                string strConnection = "Provider=Microsoft.Jet.OleDb.4.0;";
                string filePath = System.Environment.CurrentDirectory + "\\db.mdb";
                strConnection += "Data Source=" + filePath;

                objConnection = new OleDbConnection(strConnection);  //建立连接
                objConnection.Open();  //打开连接

                showText(textBlock, "数据库打开成功！");
                isGotDB = true;
            }
            catch (OleDbException er)
            {
                MessageBox.Show( "数据库连接出错！" + er.Message);
            }
            return isGotDB;
        }
        private void btn_loadFoods_Click(object sender, RoutedEventArgs e)
        {
            bool isGotDB = connectDB();
            if (isGotDB)
            {
                showFood(N_FOODS);
            }
        }
        private void showFood(int n)
        {//生成并显示n道菜；
            SP_foods.Children.Clear();
            try
            {
                sqlcmd = new OleDbCommand("select top " + n + " * from food ORDER BY food_id DESC", objConnection);  //sql语句
                reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);  //执行查询，参数表示关闭dataReader 时,同时也把与它相关联的Connection连接也一起关闭；
                showText(textBlock, "数据库查询成功！");
                while (reader.Read())
                {//Read()使reader前进到下一条记录；
                    UC_FoodItem foodItem = new UC_FoodItem();
                    foodItem.lab_id.Content = reader.GetInt32(0);
                    foodItem.lab_foodName.Content = reader.GetString(1);
                    foodItem.lab_foodPrice.Content = reader.GetFloat(2);

                    if (!reader.IsDBNull(3))
                    {
                        //载入图片；
                        Uri uri = new Uri(System.Environment.CurrentDirectory + "\\" + reader.GetString(3), UriKind.Absolute);
                        BitmapImage bitmap = new BitmapImage(uri);
                        foodItem.image.Source = bitmap;
                    }                 

                    SP_foods.Children.Add(foodItem);//将菜放到桌上；
                }
            }
            catch (OleDbException ex)
            {
                showText(textBlock, "showFood-1" + ex.Message);
            }
            catch (InvalidCastException ex)
            {
                showText(textBlock, "showFood-2" + ex.Message);
            }
        }
        public void deleteFood(string foodID)
        {
            try
            {
                Int64 food_id = Convert.ToInt64(foodID);
                //加cstr避免Access的“标准表达式类型不匹配”的问题！
                sqlcmd = new OleDbCommand("delete from food where cstr(food_id) = '" + food_id + "'", objConnection);  //sql语句
                reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);  //执行查询，参数表示关闭dataReader 时,同时也把与它相关联的Connection连接也一起关闭；
                showText(textBlock, "数据库操作执行成功！");

                SP_foods.Children.Clear();//清空桌面；
                showFood(N_FOODS);
            }
            catch (OleDbException ex)
            {
                showText(textBlock, "deleteFood-1" + ex.Message);
            }
            catch (InvalidCastException ex)
            {
                showText(textBlock, "deleteFood-2" + ex.Message);
            }
        }

        //包类型；
        const int PKT_LOGIN = 0;
        const int PKT_LOGOUT = 1;
        const int PKT_ORDER = 2;
        const int PKT_LOGIN_REPLY = 4;
        const int PKT_LOGOUT_FAILD = 5;
       
        private byte[] creatLoginPacket()
        {
            int index = 0;
            byte[] data = new byte[512];

            byte[] type = BitConverter.GetBytes(PKT_LOGIN);
            byte[] adminName = Encoding.Default.GetBytes(tb_adminName.Text);
            byte[] adminPassword = Encoding.Default.GetBytes(pb_password.Password);

            if (BitConverter.IsLittleEndian)
            {//字节序问题；
                Array.Reverse(type);
            }
            type.CopyTo(data, index);//数组拷贝；
            //index += type.Length;
            index += 4;
            adminName.CopyTo(data, index);
            index += 12;
            adminPassword.CopyTo(data, index);
            index += 12;

            return data;
        }
        private void checkLogin()
        {
            bool isSent = false;
            byte[] data = creatLoginPacket();
            try
            {
                socket.Send(data, data.Length, 0);
                socket.Send(data, data.Length, 0);//发送第二次（服务器特殊处理需要）；
                isSent = true;
            }
            catch (ArgumentException ex)
            {
                showText(textBlock_check, "参数存在错误！" + ex);
            }
            catch (SocketException ex)
            {
                showText(textBlock_check, "套接字错误！" + ex);
            }
            catch (ObjectDisposedException ex)
            {
                showText(textBlock_check, "对已释放的对象执行操作引发了错误！" + ex);
            }
            if (isSent)
            {//接收；
                receiveReply();
            }
        }
        private void receiveReply()
        {
            bool isRecv = false;
            byte[] data = new byte[4];
            try
            {
                socket.Receive(data);

                if (BitConverter.IsLittleEndian)
                {//字节序问题；
                    Array.Reverse(data);
                }

                isRecv = true;
            }
            catch (ArgumentException ex)
            {
                showText(textBlock_check, "参数存在错误！" + ex);
            }
            catch (SocketException ex)
            {
                showText(textBlock_check, "套接字错误！" + ex);
            }
            catch (ObjectDisposedException ex)
            {
                showText(textBlock_check, "对已释放的对象执行操作引发了错误！" + ex);
            }
            catch (System.Security.SecurityException ex)
            {
                showText(textBlock_check, "检测到安全性错误！" + ex);
            }
            if (isRecv)
            {//接收成功；
                int type = BitConverter.ToInt32(data, 0);

                //if (type == PKT_LOGIN_REPLY)//zheng
                if (type == 2)
                {//收到的是成功登录包；
                    showText(textBlock_check, "登录成功！");
                    btn_loadFoods.IsEnabled = true;
                    btn_add.IsEnabled = true;
                }
                else
                {
                    showText(textBlock_check, "登录出错！");
                }
            }
        }
        private void checkConnecte(TextBlock textBlock_check)
        {
            bool isConnecteSucc = false;

            showText(textBlock_check, "处理IP和端口...");
            int port = System.Int32.Parse(tb_port.Text); //取得端口号；
            string host = tb_ip.Text;
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);//把ip和端口转化为IPEndPoint实例
            showText(textBlock_check, "创建Socket...");
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个Socket

            showText(textBlock_check, "正尝试连接到服务器...");
            try
            {
                socket.Connect(ipe);//连接到服务器
                showText(textBlock_check, "已与服务器建立连接！");
                isConnecteSucc = true;
            }
            catch (ArgumentNullException ex)
            {
                showText(textBlock_check, "IP或端口错误。" + ex);
            }
            catch (SocketException ex)
            {
                showText(textBlock_check, "尝试访问套接字时发生错误。" + ex);
            }
            catch (ObjectDisposedException ex)
            {
                showText(textBlock_check, "Socket 已关闭。" + ex);
            }
            if (isConnecteSucc)
            {
                checkLogin();//检测登录；
            }
        }
        private void btn_login_Click(object sender, RoutedEventArgs e)
        {
            checkConnecte(textBlock_check);
        }
        private void btn_add_Click(object sender, RoutedEventArgs e)
        {//添加菜式到数据库；           
            bool isGotDB = connectDB();
            if (isGotDB)
            {
                addFoodToDB();
            }          
        }
        private void addFoodToDB()
        {
            string food_name = tb_addFoodName.Text;
            float food_price = Convert.ToSingle(tb_addFoodPrice.Text);
            //string food_pic;

            try
            {
                sqlcmd = new OleDbCommand("insert into [food] (food_name,[food_price]) values('" + food_name + "','" + food_price + "')", objConnection);  //sql语句
                reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);  //执行查询，参数表示关闭dataReader 时,同时也把与它相关联的Connection连接也一起关闭；
                showText(tb_addInfo, "数据库操作执行成功！");

                UC_FoodItem foodItem = new UC_FoodItem(food_name, food_price);

                grid_showFoodItem.Children.Clear();
                grid_showFoodItem.Children.Add(foodItem);
            }
            catch (OleDbException ex)
            {
                showText(tb_addInfo, "deleteFood-1" + ex.Message);
            }
            catch (InvalidCastException ex)
            {
                showText(tb_addInfo, "deleteFood-2" + ex.Message);
            }
            catch (InvalidOperationException ex)
            {
                showText(tb_addInfo, "deleteFood-3" + ex.Message);
            }
        }
        private void tabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {//（会引发启动后无界面显示,所以不用）
            if (e.Source is TabControl)
            {//do work when tab is changed 
                if ( ((TabItem)sender).Header.ToString() == "增添菜式" )
                {
                    //FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();                  
                }
            } 
        }

        private void btn_showOrder_Click(object sender, RoutedEventArgs e)
        {
            bool isGotDB = connectDB();
            if (isGotDB)
            {
                showOrder(N_FOODS);
            }
        }
        private void showOrder(int n)
        {
            SP_showOrder.Children.Clear();
            try
            {
                //相关数据表因改名为orders,应该order是Access的关键字；
                sqlcmd = new OleDbCommand("select top " + n + " * from orders order by order_id desc", objConnection);  //sql语句
                reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);  //执行查询，参数表示关闭dataReader 时,同时也把与它相关联的Connection连接也一起关闭；
                showText(textBlock, "数据库查询成功！");
                while (reader.Read())
                {//Read()使reader前进到下一条记录；
                    UC_Order order = new UC_Order(); //用户自定义控件；
                    order.lab_id.Content = reader.GetInt32(0);
                    order.lab_price.Content = reader.GetFloat(5);
                    order.lab_name.Content = reader.GetString(1);
                    order.lab_phone.Content = reader.GetString(2);
                    order.lab_building.Content = reader.GetString(3);
                    order.lab_dormitory.Content = reader.GetString(4);
                    order.tb_detail.Text = reader.GetString(6);

                    SP_showOrder.Children.Add(order);
                }
            }
            catch (OleDbException ex)
            {
                showText(tb_showOrder, "showOrder-1" + ex.Message);
            }
            catch (InvalidCastException ex)
            {
                showText(tb_showOrder, "showOrder-2" + ex.Message);
            }
        }

    }
}
